home *** CD-ROM | disk | FTP | other *** search
- /* Those who hate GOTOs (like me) B E W A R E............
- To save code space, extensive use of GOTOs was used to prevent
- repetition of code. Could SURELY be cleaner, but it works!
- KO4KS */
-
- #include <stdio.h>
- #include <time.h>
- #include <dos.h>
- #include "config.h"
- #include "bm.h"
- #include "ftpserv.h"
- #include "mailutil.h"
- #include "dirutil.h"
- #include "files.h"
- #include "smtp.h"
-
- extern int mailuser __ARGS((FILE *data,char *from,char *to,char *origto));
- extern int groupcommand __ARGS((char *action,char *group,char *user,int local, FILE **out, FILE *in));
- extern char DAEMONSTR[], Version[];
- extern char *skipwhite __ARGS((char *));
- extern char *skipnonwhite __ARGS((char *));
- extern char *Mbfwdinfo;
- extern char shortversion[], SysMessage[];
-
- static char DAEMONSTR[] = "%sREQSVR@%s (Mail Delivery Subsystem)\n";
-
- int
- rdaemon(data, from, to, msg, msgtype, mode)
- FILE *data; /* pointer to rewound data file */
- char *from, *to, *msg, msgtype;
- int mode;
- {
- time_t t;
- FILE *tfile;
- char buf[LINELEN], *newaddr, *orgto;
- long mid;
-
- if((tfile = tmpfile()) == NULLFILE)
- return -1;
- /* if (to == NULLCHAR)
- mode = 1; */
- to = strdup ((to == NULLCHAR) ? "sysop" : to);
-
- orgto = strdup (to);
- if((newaddr = rewrite_address(to)) != NULLCHAR) {
- free (to);
- to = newaddr;
- }
- time(&t);
- fprintf(tfile,Hdrs[RECEIVED]);
- fprintf(tfile,"from %s ",Hostname);
- mid = get_msgid(0);
- #ifdef MBFWD
- fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
- Hostname, (Mbfwdinfo != NULLCHAR) ? Mbfwdinfo : shortversion, \
- mid, ptime(&t));
- #else
- fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
- Hostname, shortversion, mid, ptime(&t));
- #endif
- fprintf(tfile,"%s%c\n",Hdrs[BBSTYPE], msgtype);
- fprintf(tfile,"%s%s",Hdrs[DATE],ptime(&t));
- mid = get_msgid(1);
- fprintf(tfile,"%s<%ld@%s>\n",Hdrs[MSGID],mid,Hostname);
- if (from == NULLCHAR)
- fprintf(tfile,DAEMONSTR,Hdrs[FROM],Hostname);
- else
- fprintf(tfile,"%s%s\n",Hdrs[FROM],from);
- fprintf(tfile,"%s%s\n",Hdrs[TO], orgto);
- fprintf(tfile,"%s%s\n\n",Hdrs[SUBJECT], msg);
-
- if (data != NULLFILE) {
- if (mode)
- fprintf(tfile," ===== Message %sfollows ====\n", (msg == SysMessage) ? "" : "header ");
- while(fgets(buf,sizeof(buf),data) != NULLCHAR) {
- if(mode && buf[0] == '\n')
- break;
- pwait (NULL);
- fputs(buf,tfile);
- }
- /* if (mode && (msg != SysMessage))
- fprintf(tfile," ===== Message Stored ====\n"); */
- } else
- fputc ('\n', tfile);
- rewind(tfile);
-
- sprintf (buf, "REQSVR@%s", Hostname);
- (void) mailuser(tfile, (from) ? from : buf, to, orgto);
- free (to);
- free (orgto);
- fclose(tfile);
- return 0;
- }
- #if defined(REQSVR) || defined(RMAIL)
-
- static void
- parseheader (fp, from, subject, buf, startat)
- FILE *fp;
- char *from, *subject, *buf;
- long *startat;
- {
- char *cp, *temp;
-
- rewind (fp);
- subject[0] = from[0] = 0;
- while(fgets(buf,128,fp) != NULLCHAR) {
- if(buf[0] == '\n')
- break;
- rip (buf);
- if (htype(buf) == FROM) {
- cp = &buf[strlen(Hdrs[FROM])];
- if (*cp == '"') {
- cp++;
- if ((temp = strchr (cp, '"')) != NULLCHAR)
- cp = temp+1;
- }
- if ((temp = strchr (cp, '<')) != NULLCHAR) {
- cp = temp+1;
- if ((temp = strchr (cp, '>')) != NULLCHAR)
- *temp = 0;
- }
- if ((temp = strpbrk (cp, " \t")) != NULLCHAR)
- *temp = 0;
- strcpy (from, cp);
- }
- if (htype(buf) == SUBJECT) {
- cp = &buf[strlen(Hdrs[SUBJECT])];
- cp = skipwhite(cp);
- if (*cp == '"') {
- cp++;
- if ((temp = strchr (cp, '"')) != NULLCHAR)
- *temp = 0;
- }
- strcpy (subject, cp);
- }
- }
- *startat = ftell (fp);
- if (fgets(buf,128,fp) != NULLCHAR) {
- if(!strnicmp (buf, "R:", 2)) {
- while(fgets(buf,128,fp) != NULLCHAR) {
- if(buf[0] == '\n')
- break;
- }
- *startat = ftell (fp);
- }
- }
- pwait (NULL);
- }
-
-
- static int
- handleError (fp, from, str)
- FILE *fp;
- char *from, *str;
- {
- rewind (fp);
- rdaemon (fp, NULLCHAR, from, str, 'P', 1);
- rewind (fp);
- rdaemon (fp, NULLCHAR, NULLCHAR, str, 'P', 1);
- return 0; /* pass the message back */
- }
-
-
- #endif
-
-
- #ifdef RMAIL
- static char rmailerror[] = "Rmail Error";
-
- static void
- rmailit (fp, from, to, subject, startat)
- FILE *fp;
- char *from, *to, *subject;
- long startat;
- {
- char *thisto;
-
- while (*to && to) {
- thisto = to;
- to = strchr (to, ',');
- if (to) {
- *to++ = 0;
- to = skipwhite (to);
- }
- if (!strnicmp (thisto, "rmail@", 6))
- continue;
- pwait (NULL);
- fseek (fp, startat, SEEK_SET);
- rdaemon (fp, from, thisto, subject, 'P', 0);
- }
- }
-
-
- int
- rmail (fp, from)
- FILE *fp;
- char *from;
- {
- char buf[512], subject[256], realfrom[128], *to = NULLCHAR;
- long startat;
-
- parseheader (fp, realfrom, subject, buf, &startat);
- if (realfrom[0] && subject[0]) {
- while(fgets(buf,512,fp) != NULLCHAR) {
- if(buf[0] == '\n')
- break;
- if (htype(buf) == TO) {
- if (to != NULLCHAR) { /* more than 1 To: - ERROR */
- free (to);
- to = NULLCHAR;
- break;
- } else {
- rip(buf);
- to = strdup (&buf[4]);
- }
- }
- }
- if (to != NULLCHAR) {
- rmailit (fp, realfrom, to, subject, startat);
- free (to);
- return 1;
- }
- }
- return (handleError (fp, realfrom, rmailerror));
- }
-
- #endif
-
-
-
- #ifdef REQSVR
- int
- reqsvr (fp, from)
- FILE *fp;
- char *from;
- {
- char buf[128];
- char name[128], path[128], realfrom[128];
- char subject[LINELEN], *file, cmd, *cp = path, action = 'I', *ptr, *ptr2;
- int anony = 1, mode = RETR_CMD, found = 0, first = 0;
- FILE *out, *out2;
- long prev, msgdata, privs;
- unsigned attr;
- int err;
-
- parseheader (fp, realfrom, subject, buf, &prev);
- sprintf(buf,"%s/reqsvr.log",Spool);
- if((out = fopen(buf,APPEND_TEXT)) != NULLFILE) {
- time_t t;
- time(&t);
- fprintf (out, "Received from %s (%s) on %s", realfrom, subject, ptime(&t));
- fclose (out);
- }
- if (!*subject)
- return 0; /* we are konfuzd! No subject!?!? */
- pwait (NULL);
- do {
- if (fgets(buf,128,fp) == NULLCHAR)
- break;
- if (!first && *buf == '\n')
- strcpy (buf, "R:");
- if (!strnicmp (buf, "R:", 2))
- found = 1;
- first = 1;
- } while (*buf != '\n');
- if (!found)
- fseek (fp, prev, SEEK_SET);
- /* else
- fgets(buf,128,fp); */ /* strip off blank line */
-
- /* now the fix for FBB/PRMBS/TNOS adding RFC 822-type lines to messages */
- prev = ftell (fp);
- if (fgets (buf, 128, fp) != NULLCHAR) {
- if (strnicmp (buf, "From:", 5) && strnicmp (buf, "Date:", 5) && strnicmp (buf, "Message-Id:", 11))
- fseek (fp, prev, SEEK_SET);
- else do {
- if (fgets (buf, 128,fp) == NULLCHAR)
- break;
- } while (*buf != '\n');
- }
-
- msgdata = ftell (fp);
- strncpy (name, realfrom, 40);
- file = strchr (name, '@');
- if (file)
- *file = 0;
- cmd = tolower (*subject);
- /* get senders permissions and default path */
- privs = userlogin (name, NULLCHAR, &cp, 128, &anony);
-
- file = skipnonwhite (&subject[1]);
- file = skipwhite (file);
- file = pathname (path, file);
- _dos_getfileattr (file, &attr);
- if (!strnicmp (subject, "infor", 5))
- cmd = 'f'; /* inform */
- if (!strnicmp (subject, "uni", 3))
- cmd = 'n'; /* uninform */
- if (!strnicmp (subject, "uns", 3))
- cmd = 'c'; /* unsubscribe */
-
- switch (cmd) {
- case 'i': /* info */
- case 'h': /* help */
- free (file);
- file = pathname (Helpdir, "reqsvr.hlp");
- if ((out = fopen (file, READ_TEXT)) != NULLFILE)
- goto okay;
- sprintf (buf, "Not Found %s", subject);
- goto error;
- case 'g': /* group commands */
- ptr = skipnonwhite (&subject[1]);
- ptr = skipwhite (ptr);
- cmd = tolower (*ptr);
- if (cmd != 's' && cmd != 'u' && cmd != 'l')
- if (privs == -1 || !(privs & SYSOP_CMD))
- goto denied;
-
- ptr2 = skipnonwhite (ptr);
- action = *ptr2;
- *ptr2++ = 0;
- ptr2 = skipwhite (ptr2);
- switch (cmd) {
- case 's':
- case 'u':
- case 'a':
- case 'd':
- case 'i':
- case 'l': out = NULLFILE;
- found = groupcommand (ptr, (action) ? ptr2 : NULLCHAR, realfrom, 0, &out, fp);
- *(--ptr2) = action;
- if (found) {
- if (cmd == 'l')
- goto done;
- else
- goto okay;
- } else
- goto denied;
- default: *(--ptr2) = action;
- goto confuzed;
- }
- case 'q': /* return callbook server data */
- #ifdef SAMCALLB
- ptr = skipnonwhite (&subject[1]);
- ptr = skipwhite (ptr);
- if((out = tmpfile()) != NULLFILE){
- if ((err = cb_lookup (0, ptr, out)) != 0) {
- if (err == 1)
- goto confuzed;
- else
- fprintf (out, "Amateur callsign '%s' not found or invalid\n", ptr);
- }
- goto okay;
- }
- #endif
- goto ioerror;
- case 'v': /* return version info */
- if((out = tmpfile()) != NULLFILE){
- fprintf (out, "Currently running %s at %s\n", Version, Hostname);
- goto okay;
- }
- goto ioerror;
- case 'u': /* upload a file */
- mode = STOR_CMD;
- case 's': /* subscribe to a file */
- case 'c': /* unsubscribe to a file */
- case 'f': /* inform of changes to a file */
- case 'n': /* uninform of changes to a file */
- case 'w': /* send a directory */
- case 'd': /* download a file */
- if ((privs == -1) || (!permcheck(path, privs, mode, file))) {
- denied: sprintf (buf, "Denied %s", subject);
- goto error;
- }
- switch (cmd) {
- case 'c': /* unsubscribe */
- case 'n': /* uninform */
- case 's': /* subscribe */
- case 'f': /* inform */
- if (cmd == 'c' || cmd == 's') /* subscribe functions */
- action = 'S';
- if(attr & FA_DIREC) /* whole dir */
- cp = "/";
- else {
- cp = strrchr (file, '/');
- *cp++ = 0;
- }
- sprintf(buf,"%s/reqsvr.dat",file);
- if (cmd == 's' || cmd == 'f') { /* adding functions */
- if((out = fopen(buf,APPEND_TEXT)) != NULLFILE) {
- fprintf (out, "%s %s %c\n", cp, realfrom, action);
- goto complete;
- }
- goto ioerror;
- } else { /* removing functions */
- if((out = fopen(buf,UPDATE_TEXT)) != NULLFILE) {
- while(fgets(buf,128,out) != NULLCHAR) {
- pwait (NULL);
- rip (buf);
- if (!strnicmp (buf, cp, strlen (cp)))
- if (!strnicmp ((strchr (buf, ' ') + 1), realfrom, strlen (realfrom)))
- if (buf[strlen(buf) - 1] == action) {
- fseek (out, (long) (ftell (out) - 3), SEEK_SET);
- fputc ('N', out);
- break;
- }
- }
- }
- goto complete;
- }
- case 'w': /* what (dir) */
- if((out = dir(file, 1)) == NULLFILE)
- goto ioerror;
- goto okay;
- case 'u': /* upload */
- if ((out = fopen (file, WRITE_TEXT)) == NULLFILE) {
- ioerror: sprintf (buf, "IO Error %s", subject);
- goto error;
- }
- while(fgets(buf,128,fp) != NULLCHAR) {
- pwait (NULL);
- fputs(buf,out);
- }
- fclose (out);
- cp = strrchr (file, '/');
- *cp++ = 0;
- sprintf(buf,"%s/reqsvr.dat",file);
- if((out = fopen(buf,READ_TEXT)) != NULLFILE) {
- if((out2 = tmpfile()) != NULLFILE)
- fprintf (out2, "File changed by %s\n", realfrom);
- while(fgets(name,128,out) != NULLCHAR) {
- pwait (NULL);
- if (*name == '/' || !strnicmp (name, cp, strlen (cp))) {
- ptr = strrchr (name, ' ');
- *ptr = 0;
- action = ptr[1];
- ptr = (strchr (name, ' ') + 1);
- switch (action) {
- case 'S':
- sprintf (buf, "Subscribe %s/%s", file, cp);
- fseek (fp, msgdata, SEEK_SET);
- rdaemon (fp, NULLCHAR, ptr, buf, 'P', 0);
- break;
- case 'I':
- sprintf (buf, "Inform %s/%s", file, cp);
- if (out2 != NULLFILE)
- rewind (out2);
- rdaemon (out2, NULLCHAR, ptr, buf, 'P', 0);
- break;
- }
- }
- }
- if (out2 != NULLFILE)
- fclose (out2);
- }
- complete: if (out != NULLFILE) {
- fclose (out);
- out = NULLFILE;
- }
- goto okay;
- case 'd': /* download */
- if ((out = fopen (file, READ_TEXT)) == NULLFILE)
- goto ioerror;
- okay: sprintf (buf, "Accepted %s", subject);
- if (out != NULLFILE)
- rewind (out);
- rdaemon (out, NULLCHAR, realfrom, buf, 'P', 0);
- if (out != NULLFILE)
- fclose (out);
- }
- break;
- confuzed:
- default: sprintf (buf, "Unknown %s", subject);
- goto error;
- }
- done: free (file);
- return 1; /* we handled it, here! */
-
- error: free (file);
- return (handleError (fp, realfrom, buf));
- }
-
- #endif
-